package com.github.florent37.shapeofview.shapes;


import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Switch;
import ohos.agp.render.BlendMode;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import com.github.florent37.shapeofview.manager.ResourceTable;

/**
 * CutCornerMeterialDesigView
 *
 * @since 2021-07-26
 */
public class CutCornerMeterialDesigView extends StackLayout implements Component.EstimateSizeListener, Component.DrawTask {
    private final static int mWegiHeight = 10;
    private final Rect rectF = new Rect();
    private Paint paint = new Paint();
    private Path mPath;
    private int mWidth;
    private int mHeight;
    private String shape_text;
    private float topLeftCutSizePx = 0f;
    private float topRightCutSizePx = 0f;
    private float bottomRightCutSizePx = 0f;
    private float bottomLeftCutSizePx = 0f;
    private int shapemode = 1;
    private PixelMapHolder pmh01;
    private PixelMapHolder pmh02;

    /**
     * CutCornerMeterialDesigView
     *
     * @param context context
     */
    public CutCornerMeterialDesigView(Context context) {
        super(context);
        init(context, null);
    }

    /**
     * CutCornerMeterialDesigView
     *
     * @param context context
     * @param attrs attrs
     */
    public CutCornerMeterialDesigView(Context context, AttrSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    /**
     * CutCornerMeterialDesigView
     *
     * @param context context
     * @param attrs attrs
     * @param defStyleAttr defStyleAttr
     */
    public CutCornerMeterialDesigView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, String.valueOf(defStyleAttr));
        init(context, attrs);
    }

    private void init(Context context, AttrSet attrs) {
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL_STYLE);
        paint.setStrokeWidth(10);
        paint.setStrokeJoin(Paint.Join.MITER_JOIN);
        if (attrs != null) {
            topLeftCutSizePx = attrs.getAttr("shape_cutCorner_topLeftSize").get().getFloatValue();
            topRightCutSizePx = attrs.getAttr("shape_cutCorner_topRightSize").get().getFloatValue();
            bottomLeftCutSizePx = attrs.getAttr("shape_cutCorner_bottomLeftSize").get().getFloatValue();
            bottomRightCutSizePx = attrs.getAttr("shape_cutCorner_bottomRightSize").get().getFloatValue();
            shape_text = attrs.getAttr("shape_text").get().getStringValue();
            shapemode = attrs.getAttr("shape_mode").get().getIntegerValue();
        }
        setEstimateSizeListener(this::onEstimateSize);
        addDrawTask(this::onDraw);
    }

    @Override
    public boolean onEstimateSize(int width, int height) {
        mWidth = EstimateSpec.getSize(width);
        mHeight = EstimateSpec.getSize(height);
        return false;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        rectF.set(0, 0, getWidth(), getHeight());
        mPath = generatePath(rectF, topLeftCutSizePx, topRightCutSizePx, bottomRightCutSizePx, bottomLeftCutSizePx);
        mPath.close();
        switch (shapemode) {
            case 0:
                paint.setColor(Color.WHITE);
                canvas.drawPath(mPath, paint);
                pmh01 = new PixelMapHolder(getPixelMap(ResourceTable.Media_shape_of_view_tea_cup));
                canvas.drawPixelMapHolder(pmh01, 200, 100, paint);
                paint.setBlendMode(BlendMode.SRC_IN);
                paint.setColor(Color.BLACK);
                paint.setStrokeWidth(30);
                paint.setTextSize(40);
                paint.setTextAlign(TextAlignment.CENTER);
                canvas.drawText(paint, "Hight Tea Cup", getWidth() / 2, getHeight() / 3);
                canvas.drawText(paint, "$36", getWidth() / 2, getHeight() / 3 + 60);
                pmh02 = new PixelMapHolder(getPixelMap(ResourceTable.Media_shape_of_view_shoes));
                canvas.drawPixelMapHolder(pmh02, 200, getHeight() / 3 + 200, paint);
                canvas.drawText(paint, "Hopscotch Shoes", getWidth() / 2, getHeight() - mHeight - 100);
                canvas.drawText(paint, "$36", getWidth() / 2, getHeight() - mHeight - 40);
                break;
            case 1:
                paint.setColor(new Color(Color.getIntColor("#FEDBD0")));
                canvas.drawPath(mPath, paint);
                pmh01 = new PixelMapHolder(getPixelMap(ResourceTable.Media_shopcart));
                canvas.drawPixelMapHolder(pmh01, 40, 20, paint);
                paint.setBlendMode(BlendMode.SRC_IN);
                break;
            case 2:
                paint.setColor(Color.WHITE);
                canvas.drawPath(mPath, paint);
                pmh01 = new PixelMapHolder(getPixelMap(ResourceTable.Media_shopcart));
                canvas.drawPixelMapHolder(pmh01, 220, 50, paint);
                paint.setBlendMode(BlendMode.SRC_IN);
                paint.setColor(Color.BLACK);
                paint.setStrokeWidth(30);
                paint.setTextSize(40);
                paint.setTextAlign(TextAlignment.CENTER);
                canvas.drawText(paint, "ADD TO CART", getWidth() / 2, getHeight() / 2 + 20);
                break;
        }
        paint.setBlendMode(null);
    }

    /**
     * updateUi
     */
    public void updateUi() {
        rectF.set(0, 0, mWidth, mHeight);
        mPath.set(generatePath(rectF, topLeftCutSizePx, topRightCutSizePx, bottomRightCutSizePx, bottomLeftCutSizePx));
        this.setVisibility(Component.VISIBLE);
        invalidate();
    }

    private Path generatePath(Rect rect, float topLeftDiameter, float topRightDiameter, float bottomRightDiameter, float bottomLeftDiameter) {
        final Path path = new Path();
        topLeftDiameter = topLeftDiameter < 0 ? 0 : topLeftDiameter;
        topRightDiameter = topRightDiameter < 0 ? 0 : topRightDiameter;
        bottomLeftDiameter = bottomLeftDiameter < 0 ? 0 : bottomLeftDiameter;
        bottomRightDiameter = bottomRightDiameter < 0 ? 0 : bottomRightDiameter;

        path.moveTo(rect.left + topLeftDiameter, rect.top);
        path.lineTo(rect.right - topRightDiameter, rect.top);
        path.lineTo(rect.right, rect.top + topRightDiameter);
        path.lineTo(rect.right, rect.bottom - bottomRightDiameter);
        path.lineTo(rect.right - bottomRightDiameter, rect.bottom);
        path.lineTo(rect.left + bottomLeftDiameter, rect.bottom);
        path.lineTo(rect.left, rect.bottom - bottomLeftDiameter);
        path.lineTo(rect.left, rect.top + topLeftDiameter);
        path.lineTo(rect.left + topLeftDiameter, rect.top);
        path.close();

        return path;
    }

    /**
     * getTopLeftCutSize
     *
     * @return float
     */
    public float getTopLeftCutSize() {
        return topLeftCutSizePx;
    }

    /**
     * setTopLeftCutSize
     *
     * @param topLeftCutSize topLeftCutSize
     */
    public void setTopLeftCutSize(float topLeftCutSize) {
        this.topLeftCutSizePx = topLeftCutSize;
        invalidate();
    }

    /**
     * getTopRightCutSize
     *
     * @return float
     */
    public float getTopRightCutSize() {
        return topRightCutSizePx;
    }

    /**
     * setTopRightCutSize
     *
     * @param topRightCutSize topRightCutSize
     */
    public void setTopRightCutSize(float topRightCutSize) {
        this.topRightCutSizePx = topRightCutSize;
        invalidate();
    }

    /**
     * getBottomRightCutSize
     *
     * @return float
     */
    public float getBottomRightCutSize() {
        return bottomRightCutSizePx;
    }

    /**
     * setBottomRightCutSize
     *
     * @param bottomRightCutSize bottomRightCutSize
     */
    public void setBottomRightCutSize(float bottomRightCutSize) {
        this.bottomRightCutSizePx = bottomRightCutSize;
        invalidate();
    }

    /**
     * getBottomLeftCutSize
     *
     * @return float
     */
    public float getBottomLeftCutSize() {
        return bottomLeftCutSizePx;
    }

    public void setBottomLeftCutSize(float bottomLeftCutSize) {
        this.bottomLeftCutSizePx = bottomLeftCutSize;
        invalidate();
    }

    private PixelMap getPixelMap(int resourceId) {
        try {
            Resource resource = getResourceManager().getResource(resourceId);
            ImageSource imageSource = ImageSource.create(resource, new ImageSource.SourceOptions());
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            switch (shapemode) {
                case 0:
                    decodingOptions.desiredSize = new Size(imageSource.getImageInfo().size.width + 120, imageSource.getImageInfo().size.height - 200);
                    break;
                case 1:
                    decodingOptions.desiredSize = new Size(imageSource.getImageInfo().size.width / 2 - 20, imageSource.getImageInfo().size.height / 2 - 20);
                    break;
                case 2:
                    decodingOptions.desiredSize = new Size(imageSource.getImageInfo().size.width / 2 - 20, imageSource.getImageInfo().size.height / 2 - 20);
                    break;
            }

            decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
            PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
            mWidth = pixelMap.getImageInfo().size.width;
            mHeight = pixelMap.getImageInfo().size.height;
            System.out.println("getheight : " + mWidth);
            System.out.println("width : " + mHeight);
            return pixelMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
